package client

import (
	"context"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/micro/go-micro/v2/client"
	"github.com/micro/go-micro/v2/client/grpc"

	"kop/framework/errors"
	"kop/framework/wrapper"
	"kop/modules/item/consts"
	"kop/pb"
	"kop/pb/service"
)

var ItemService service.ItemService

func init() {

	var c = grpc.NewClient(client.Wrap(wrapper.ClientLogWrapper))
	_ = c.Init()

	ItemService = service.NewItemService("go.micro.srv.item", c)
}

func GetItems(ctx context.Context) []*pb.Item {

	var resp, err = ItemService.GetItems(ctx, &empty.Empty{})
	if err != nil {
		panic(err)
	}

	return resp.Items
}

// return pb.Item
func GetItem(roleID, itemID int32) *pb.Item {

	var item, err = ItemService.GetItem(context.Background(), &service.DefaultRequest{RoleID: roleID, Value: itemID})
	if err != nil {
		panic(err)
	}

	return item.Item
}

//func save(roleID int32, item *pb.Item) {
//
//	var resp, err = srv.Save(context.Background(), &service.SaveItemRequest{RoleID: roleID, Item: item})
//	if err != nil {
//		panic(err)
//	}
//	*item = *resp
//}

//func AsyncSave(roleID int32, item *pb.Item) error {
//	var _, err = srv.AsyncSave(context.Background(), &service.SaveItemRequest{RoleID: roleID, Item: item})
//	return err
//}

func AddItem(roleID, itemID, number int32) *pb.Item {

	var item, err = ItemService.Add(context.Background(), &service.ItemRequest{RoleID: roleID, RawItem: &pb.RawItem{ItemID: itemID, Number: number}})
	if err != nil {
		panic(err)
	}

	return item
}

//
func DelItem(roleID, serverID, itemID, number int32) (*pb.Item, error) {

	return ItemService.Del(context.Background(), &service.ItemRequest{RoleID: roleID, ServerID: serverID, RawItem: &pb.RawItem{ItemID: itemID, Number: number}})
}

// go broker
func AsyncDelItem(roleID, serverID, itemID, number int32) error {

	var _, err = ItemService.AsyncDel(context.Background(), &service.ItemRequest{RoleID: roleID, ServerID: serverID, RawItem: &pb.RawItem{ItemID: itemID, Number: number}})
	return err
}

type Prepare struct {
	RoleID   int32
	ServerID int32
	rawItem  pb.RawItem
	item     *pb.Item
}

func (p *Prepare) Prepare(itemID, number int32) (*Prepare, error) {

	p.rawItem = pb.RawItem{ItemID: itemID, Number: number}

	var err error
	p.item = GetItem(p.RoleID, itemID)
	if p.item == nil || p.item.Number < number {

		switch itemID {
		case consts.Gold:
			err = errors.GoldNotEnoughError
		case consts.Diamond:
			err = errors.DiamondNotEnoughError
		default:
			err = errors.ItemNotEnoughError
		}

	}

	return p, err
}

func (p *Prepare) Run() (*pb.Item, error) {

	return ItemService.Del(context.Background(), &service.ItemRequest{RoleID: p.RoleID, ServerID: p.ServerID, RawItem: &p.rawItem})
}

func (p *Prepare) AsyncRun() (err error) {

	_, err = ItemService.Del(context.Background(), &service.ItemRequest{RoleID: p.RoleID, ServerID: p.ServerID, RawItem: &p.rawItem})
	return err
}

// 删除道具预加载
func NewPrepare(roleID, serverID int32) *Prepare {

	return &Prepare{RoleID: roleID, ServerID: serverID}
}
